Omplus.models.Array = Omplus.base.extend(Omplus.models.MultiElement, {
    omplusType:"Array",
    value:[],
    omplusProto:null,
    destroy:function () {
        this.empty();
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnDestroyModel").notify(this.controller);
        for (var i in this.events) {
            delete Omplus.globals.objects[this.omplusName + "." + this.events[i]];
        }
        for (var i in this.validators) {
            delete Omplus.globals.objects[this.omplusName + "." + this.validators[i]];
        }
        delete Omplus.globals.objects[this.omplusName];
    },
    pushMember:function (newValue) {
        var omplusName = this.getOmplusName(newValue);
        Omplus.base.create(Omplus.models[this.omplusProto], {
            omplusName:omplusName,
            controller:this.controller
        });
        Omplus.globals.getObject(omplusName).setValue(newValue);
        this.value.push(Omplus.globals.getObject(omplusName));

    },
    getMemberByName:function (name) {
        return Omplus.globals.getObject(name);
    },
    getMemberByIndex:function (index) {
        return this.value[index];
    },
    empty:function () {
        while (this.value.length) {
            if (Omplus.globals.objects[this.value[0].omplusName])
                Omplus.globals.objects[this.value[0].omplusName].destroy();
            this.value.splice(0, 1);
        }
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, null, this.isValid()]);
    },
    setValue:function (newValue, view) {
        this.empty();
        for (var i in newValue) {
            this.pushMember(newValue[i]);
        }
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, view, this.isValid()]);
    },
    getValue:function () {
        var object = [];
        for (var i in this.value) {
            object[i] = this.value[i].getValue();
        }
        return object;
    },
    getOmplusName:function (newValue) {
        return this.omplusName + ".member." + this.value.length;
    }
});

Omplus.models.Object = Omplus.base.extend(Omplus.models.MultiElement, {
    omplusType:"Object",
    value:{},
    empty:function () {
        for (var i in this.value) {
            this.value[i].empty();
        }
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, null, true]);
    }
});

Omplus.models.ErrorValue = Omplus.base.extend(Omplus.models.Object, {
    omplusType:"ErrorValue"
});

Omplus.models.Errors = Omplus.base.extend(Omplus.models.Array, {
    omplusType:"Errors",
    omplusProto:"ErrorValue",
    pushMember:function (newValue) {
        if (Omplus.globals.getObject("Assets.list." + newValue.value))
            this.value.push(Omplus.globals.getObject("Assets.list." + newValue.value));
    },
    empty:function () {
        while (this.value.length) {
            this.value.splice(0, 1);
        }
    }
});

Omplus.models.Model = Omplus.base.extend(Omplus.models.Object, {
    init:function () {
        var omplusName = this.omplusName + ".errors";
        this.errors = Omplus.base.create(Omplus.models.Errors, {
            omplusName:omplusName,
            controller:this.controller
        });
        omplusName = this.omplusName + ".status";
        this.status = Omplus.base.create(Omplus.models.String, {
            omplusName:omplusName,
            controller:this.controller
        });
        for (var i in this.actions) {
            this.actions[i].omplusName = this.omplusName + "." + this.actions[i].omplusName;
            this.actions[i] = Omplus.base.create(Omplus.actions[this.actions[i].omplusType], this.actions[i]);
        }
    },
    omplusType:"Model",
    value:{},
    status:null,
    errors:null,
    actions:[],

    destroy:function () {
        for (var i in this.value) {
            if (this.value[i])
                this.value[i].destroy();
        }
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnDestroyModel").notify(this.controller);
        for (var i in this.events) {
            delete Omplus.globals.objects[this.omplusName + "." + this.events[i]];
        }
        for (var i in this.validators) {
            delete Omplus.globals.objects[this.omplusName + "." + this.validators[i]];
        }
        for (var i in this.actions) {
            delete Omplus.globals.objects[this.omplusName + "." + this.actions[i].omplusName];
        }
        this.errors.destroy();
        this.status.destroy();
        delete Omplus.globals.objects[this.omplusName];
    },
    getAction:function (actionName) {
        return Omplus.globals.getObject(this.omplusName + "." + actionName);
    },
    setStatus:function (status) {
        this.status.setValue(status);
    },
    getStatus:function () {
        return this.status.getValue();
    },
    setErrors:function (errors) {
        this.errors.setValue(errors);
    }
});

Omplus.models.SingleChooser = Omplus.base.extend(Omplus.models.Object, {
    init:function () {
        this.value.current = Omplus.base.create(Omplus.models[this.omplusProto], {
            omplusName:this.omplusName + ".current",
            controller:this.controller
        });
        this.value.list = Omplus.base.create(Omplus.models.Array, {
            omplusName:this.omplusName + ".list",
            getOmplusName:this.getOmplusName,
            omplusProto:this.omplusProto,
            controller:this.controller
        });
        for (var i in this.actions) {
            this.actions[i].omplusName = this.omplusName + "." + this.actions[i].omplusName;
            this.actions[i] = Omplus.base.create(Omplus.actions[this.actions[i].omplusType], this.actions[i]);
        }
    },
    omplusType:"SingleChooser",
    omplusProto:null,
    currentIndex:null,
    setValue:function (newValue, view) {
        for (var i in newValue) {
            if (this.value[i])
                this.value[i].setValue(newValue[i], view)
        }
        if (!newValue["current"] && this.value.list.value.length) {
            this.value.current.setValue(this.value.list.value[0].getValue());
            this.currentIndex = 0;
        } else if (newValue["current"]) {
            this.value.current
        }
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, view, this.isValid()]);
    },
    chooseByIndex:function (index) {
        if (this.value.list.value.length && this.value.list.value[index]) {
            this.value.current.setValue(this.value.list.value[index].getValue());
            this.currentIndex = index;
        }
    },
    chooseLast:function () {
        if (this.value.list.value.length ) {
            this.chooseByIndex(this.value.list.value.length - 1);
        }
    },
    removeByIndex:function (index) {
        if (this.value.list.value.length && this.value.list.value[index]) {
            this.value.list.value[index].destroy();
            this.value.list.value.splice(index, 1);
            if (index == this.currentIndex && this.value.list.value.length) {
                this.value.current.setValue(this.value.list.value[0].getValue());
                this.currentIndex = 0;
            }
        }
    },
    getValue:function () {
        var object = new Object();
        for (var i in this.value) {
            object[i] = this.value[i].getValue();
        }
        object["selected"] = this.currentIndex;
        return object;
    },
    getAction:function (actionName) {
        return Omplus.globals.getObject(this.omplusName + "." + actionName);
    },
    addToList:function (newValue, choose, find) {
        var list = this.value.list.getValue();
        var isset = false;
        if (find)
            for (var i in list) {
                if (newValue[find] == list[i][find]) {
                    isset = true;
                    if (choose)
                        this.chooseByIndex(i);
                }
            }
        if (!isset) {
            this.value.list.pushMember(newValue);
            if (choose)
                this.chooseByIndex(this.value.list.length - 1);
        }
        if (this.controller) {
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, null, this.isValid()]);
        }
    },
    getOmplusName:function (newValue) {
        return this.omplusName + ".member." + this.value.length;
    },
    saveCurrent : function(){
        this.value.list.value[this.currentIndex].setValue(this.value.current.getValue());
    }
});


Omplus.models.MultiChooser = Omplus.base.extend(Omplus.models.Object, {
    init:function () {
        this.value.current = Omplus.base.create(Omplus.models.Array, {
            omplusName:this.omplusName + ".current",
            omplusProto:this.omplusProto,
            controller:this.controller
        });
        this.value.list = Omplus.base.create(Omplus.models.Array, {
            omplusName:this.omplusName + ".list",
            omplusProto:this.omplusProto,
            controller:this.controller
        });
    },
    omplusType:"MultiChooser",
    omplusProto:null,
    currentIndexes:null,
    setValue:function (newValue, view) {
        for (var i in newValue) {
            this.value[i].setValue(newValue[i], view)
        }
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, view, this.isValid()]);
    },
    chooseByIndexes:function (indexes) {
        this.currentIndexes = [];
        var array = [];
        for (var index in indexes) {
            if (this.value.list.value.length && this.value.list.value[indexes[index]]) {
                array.push(this.value.list.value[indexes[index]].getValue());
                this.currentIndexes.push(indexes[index]);
            }
        }
        this.value.current.setValue(array);

    },
    removeByIndexes:function (indexes) {
        indexes.sort(function (a, b) {
            return b - a
        });
        for (var index in indexes) {
            if (this.value.list.value.length && this.value.list.value[indexes[index]]) {
                this.value.list.value[indexes[index]].destroy();
                this.value.list.value.splice(indexes[index], 1);
                if (this.currentIndexes.indexOf(indexes[index]) != -1) {
                    this.currentIndexes.splice(this.currentIndexes.indexOf(indexes[index]), 1);
                }
            }
        }
        var array = [];
        for (var index in this.currentIndexes) {
            if (this.value.list.value.length && this.value.list.value[this.currentIndexes[index]]) {
                array.push(this.value.list.value[this.currentIndexes[index]].getValue());
            }
        }
        this.value.current.setValue(array);
    },
    getValue:function () {
        var object = new Object();
        for (var i in this.value) {
            object[i] = this.value[i].getValue();
        }
        object["selected"] = this.currentIndexes;
        return object;
    }

});


Omplus.models.MultiDifferentChooser = Omplus.base.extend(Omplus.models.Object, {
    init:function () {
        for (var i in this.currentModels) {
            this.value[this.currentModels[i]] = Omplus.base.create(Omplus.models[this.omplusProto], {
                omplusName:this.omplusName + "." + this.currentModels[i],
                controller:this.controller
            });
            this.currentIndex[this.currentModels[i]] = null;
        }
        this.value.list = Omplus.base.create(Omplus.models.Array, {
            omplusName:this.omplusName + ".list",
            getOmplusName:this.getOmplusName,
            omplusProto:this.omplusProto,
            controller:this.controller
        });
    },
    omplusType:"MultiDifferentChooser",
    omplusProto:null,
    currentIndex:{},
    currentModels:[],
    setValue:function (newValue, view) {
        for (var i in newValue) {
            if (this.value[i])
                this.value[i].setValue(newValue[i], view)
        }
        for (var i in this.currentModels) {
            if (!newValue[this.currentModels[i]] && this.value.list.value.length) {
                this.value[this.currentModels[i]].setValue(this.value.list.value[0].getValue());
                this.currentIndex[i] = 0;
            }
        }
        if (this.controller)
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, view, this.isValid()]);
    },
    chooseByIndex:function (index, model) {
        if (this.value.list.value.length && this.value.list.value[index]) {
            this.value[model].setValue(this.value.list.value[index].getValue());
            this.currentIndex[model] = index;
        }
    },
    removeByIndex:function (index, model) {
        if (this.value.list.value.length && this.value.list.value[index]) {
            this.value.list.value[index].destroy();
            this.value.list.value.splice(index, 1);
            if (index == this.currentIndex[model] && this.value.list.value.length) {
                this.value[model].setValue(this.value.list.value[0].getValue());
                this.currentIndex[model] = 0;
            }
        }
    },
    getValue:function () {
        var object = new Object();
        for (var i in this.value) {
            object[i] = this.value[i].getValue();
        }
        object["selected"] = this.currentIndex;
        return object;
    },
    addToList:function (newValue, choose, find) {
        var list = this.value.list.getValue();
        var isset = false;
        if (find)
            for (var i in list) {
                if (newValue[find] == list[i][find]) {
                    isset = true;
                    if (choose)
                        this.chooseByIndex(i);
                }
            }
        if (!isset) {
            this.value.list.pushMember(newValue);
            if (choose)
                this.chooseByIndex(this.value.list.length - 1);
        }
        if (this.controller) {
            Omplus.globals.getObject(this.omplusName + ".OnUpdateModel").notify([this.controller, null, this.isValid()]);
        }
    },
    getOmplusName:function (newValue) {
        return this.omplusName + ".member." + this.value.length;
    }

});